﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Net8.Project.Extension
{
    /// <summary>
    /// Redis 缓存操作接口
    /// </summary>
    [Description("普通缓存建议直接使用 ICaching，如需使用 Redis 队列等功能请使用此接口")]
    public interface IRedisBasket
    {
        #region 基础缓存操作

        /// <summary>
        /// 获取指定 key 的字符串值
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>返回缓存中的字符串值</returns>
        Task<string> GetValue(string key);

        /// <summary>
        /// 获取指定 key 的对象值，并反序列化为 TEntity 类型
        /// </summary>
        /// <typeparam name="TEntity">目标类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns>返回反序列化后的对象</returns>
        Task<TEntity> Get<TEntity>(string key);

        /// <summary>
        /// 设置指定 key 的缓存值
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="cacheTime">缓存有效时间</param>
        Task Set(string key, object value, TimeSpan cacheTime);

        /// <summary>
        /// 判断指定 key 是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>返回是否存在</returns>
        Task<bool> Exist(string key);

        /// <summary>
        /// 移除指定 key 的缓存
        /// </summary>
        /// <param name="key">缓存键</param>
        Task Remove(string key);

        /// <summary>
        /// 清空所有缓存值
        /// </summary>
        Task Clear();

        #endregion

        #region List 操作

        /// <summary>
        /// 获取指定 key 对应的所有列表项（以 RedisValue 数组形式返回）
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <returns>返回 RedisValue 数组</returns>
        Task<RedisValue[]> ListRangeAsync(string redisKey);

        /// <summary>
        /// 从列表左侧插入一个元素
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="redisValue">插入的值</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回插入后列表的长度</returns>
        Task<long> ListLeftPushAsync(string redisKey, string redisValue, int db = -1);

        /// <summary>
        /// 从列表右侧插入一个元素
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="redisValue">插入的值</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回插入后列表的长度</returns>
        Task<long> ListRightPushAsync(string redisKey, string redisValue, int db = -1);

        /// <summary>
        /// 从列表右侧批量插入多个元素
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="redisValue">插入的值集合</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回插入后列表的长度</returns>
        Task<long> ListRightPushAsync(string redisKey, IEnumerable<string> redisValue, int db = -1);

        /// <summary>
        /// 从列表左侧弹出一个元素，并反序列化为 T 类型对象
        /// </summary>
        /// <typeparam name="T">目标类型，限制为引用类型</typeparam>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回反序列化后的对象</returns>
        Task<T> ListLeftPopAsync<T>(string redisKey, int db = -1) where T : class;

        /// <summary>
        /// 从列表右侧弹出一个元素，并反序列化为 T 类型对象
        /// </summary>
        /// <typeparam name="T">目标类型，限制为引用类型</typeparam>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回反序列化后的对象</returns>
        Task<T> ListRightPopAsync<T>(string redisKey, int db = -1) where T : class;

        /// <summary>
        /// 从列表左侧弹出一个字符串
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回弹出的字符串</returns>
        Task<string> ListLeftPopAsync(string redisKey, int db = -1);

        /// <summary>
        /// 从列表右侧弹出一个字符串
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回弹出的字符串</returns>
        Task<string> ListRightPopAsync(string redisKey, int db = -1);

        /// <summary>
        /// 获取列表的长度
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回列表长度</returns>
        Task<long> ListLengthAsync(string redisKey, int db = -1);

        /// <summary>
        /// 获取指定 key 的所有列表项（返回字符串集合）
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回字符串集合</returns>
        Task<IEnumerable<string>> ListRangeAsync(string redisKey, int db = -1);

        /// <summary>
        /// 获取列表中指定范围内的项（返回字符串集合）
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="start">起始索引</param>
        /// <param name="stop">结束索引</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回指定范围内的字符串集合</returns>
        Task<IEnumerable<string>> ListRangeAsync(string redisKey, int start, int stop, int db = -1);

        /// <summary>
        /// 删除列表中指定的元素
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="redisValue">要删除的值</param>
        /// <param name="type">
        /// 删除策略：
        /// 0 表示删除所有匹配； 1 表示从头部开始删除； -1 表示从尾部开始删除
        /// </param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        /// <returns>返回删除的元素个数</returns>
        Task<long> ListDelRangeAsync(string redisKey, string redisValue, long type = 0, int db = -1);

        /// <summary>
        /// 清空指定 key 对应的列表
        /// </summary>
        /// <param name="redisKey">列表键</param>
        /// <param name="db">数据库编号，默认 -1 表示使用默认库</param>
        Task ListClearAsync(string redisKey, int db = -1);

        #endregion
    }
}